home *** CD-ROM | disk | FTP | other *** search
- unit setjmps;
- {$F+} {$O-}
- { SETJMPS.PAS
-
- This code supports setjmp/jmpback (jmpback is a better name than longjmp)
- in Turbo Pascal 5.x, 6.0 -- and was specially created for use with
- "jumping back" between overlayed units.
-
- setjmp/jmpback are great for dealing with errors and exceptions
- in low-level procedures.
-
- about setjmp: (adapted from Turbo C++ Library Reference Manual)
-
- setjmp sets up for a nonlocal goto. When called it stores the
- 'task state' in buf and returns 0. Later, calling jmpback with
- a ret value and this saved 'task state' buffer causes a special
- goto to occurr that makes setjmp appear to have returned AGAIN
- with the ret value passed to jmpback. (did that make sense?).
-
- In order to support overlays I had to deviate from the C definition
- and pass another parameter to setjmp. This extra parameter is the
- address of a function (ala procedure variable: localCS) that simply
- returns the Cseg of the unit to jmpback to. jmpback calls this
- procedure before performing the nonlocal goto--this makes sure an
- overlayed unit is actually in memory before jumping back to it.
- ** Every call to setjmp must pass a function that returns the Cseg
- of the unit that contains the setjmp call. If setjmp is called
- in several different units, EACH UNIT must have IT'S OWN localCS
- function.
- localCS functions should look something like this:
-
- function localCSfunction:word;
- begin
- localCSfunction := Cseg;
- end;
- (if you didn't understand all that, just look at the example
- files to see how to declare and use the function: localCSfunction).
-
- setjmp must be called before jmpback. The routine that calls
- setjmp must still be active and cannot have returned before jmpback
- is called.
-
-
- Author: David Stephens, compuserve 71621,2210.
- april/91
- author's note: The use of the localCS procedureal variable is clumsy,
- but is version-independent enough to work in 5.x and 6.0.
- If you figure out a better way of dealing with the
- overlayed unit problem than the localCS variable,
- please let me know.
-
- finally: I'm giving this code 'as is' to the public domain, to be used
- and abused by the unwashed masses. Use the code at your own
- risk; I won't accept responsibility for any damages it might
- cause. I would appreciate being mentioned in any 'improved
- versions' that are derived from this work.
-
- }
- interface
- TYPE
- jmpCSfunc = function:word;
- jmpbuf = record {no not 'jmp_buf', I'm underbar-impaired}
- localCS : jmpCSfunc;
- ss,sp,bp : word;
- ip,cs : word;
- end;
-
- function setjmp(VAR buf:jmpBuf; CSfunc:jmpCSfunc) : integer;
- procedure jmpback(VAR buf:jmpBuf; ret:integer);
-
- implementation
-
- {$L setjmp}
- function setjmp(VAR buf:jmpBuf; CSfunc:jmpCSfunc) : integer; external;
- procedure jmpBack(VAR buf:jmpBuf; ret:integer); external;
-
- end.
-